package controllers

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/vulnark/vulnark/models"
	"github.com/vulnark/vulnark/utils"
)

// VulnerabilityController 漏洞控制器
type VulnerabilityController struct{}

// ListVulnerabilities 获取漏洞列表
func (v *VulnerabilityController) ListVulnerabilities(c *gin.Context) {
	// 获取查询参数
	keyword := c.Query("keyword")
	severity := c.Query("severity")
	status := c.Query("status")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))

	// 构建查询
	query := utils.DB.Model(&models.Vulnerability{})

	// 条件过滤
	if keyword != "" {
		query = query.Where("title LIKE ? OR cve LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
	}
	if severity != "" {
		query = query.Where("severity = ?", severity)
	}
	if status != "" {
		query = query.Where("status = ?", status)
	}

	// 获取总数
	var total int64
	query.Count(&total)

	// 获取分页数据，预加载关联的资产
	var vulnerabilities []models.Vulnerability
	query.Preload("Assets").Limit(pageSize).Offset((page - 1) * pageSize).Order("created_at DESC").Find(&vulnerabilities)

	// 转换为响应格式
	var responseItems []map[string]interface{}
	for _, vuln := range vulnerabilities {
		// 提取关联资产信息
		var assets []map[string]interface{}
		for _, asset := range vuln.Assets {
			assets = append(assets, map[string]interface{}{
				"id":   asset.ID,
				"name": asset.Name,
				"type": asset.Type,
			})
		}

		item := map[string]interface{}{
			"id":            vuln.ID,
			"title":         vuln.Title,
			"cve_id":        vuln.CVE,
			"description":   vuln.Description,
			"severity":      vuln.Severity,
			"status":        vuln.Status,
			"cvss":          vuln.CVSS,
			"type":          vuln.Type,
			"reported_by":   vuln.ReportedBy,
			"discovered_at": utils.FormatTimeCST(vuln.DiscoveredAt),
			"created_at":    vuln.CreatedAt,
			"updated_at":    vuln.UpdatedAt,
			"assets":        assets, // 添加关联资产到响应
		}
		responseItems = append(responseItems, item)
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data": gin.H{
			"items": responseItems,
			"total": total,
		},
	})
}

// GetVulnerabilityByID 获取单个漏洞信息
func (v *VulnerabilityController) GetVulnerabilityByID(c *gin.Context) {
	id := c.Param("id")
	log.Printf("获取漏洞详情, ID: %s", id)

	var vulnerability models.Vulnerability

	// 使用显式预加载关联的资产
	if err := utils.DB.Preload("Assets").First(&vulnerability, id).Error; err != nil {
		log.Printf("漏洞不存在, ID: %s, 错误: %v", id, err)
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": "漏洞不存在",
		})
		return
	}

	// 检查关联的资产是否成功加载
	if len(vulnerability.Assets) > 0 {
		log.Printf("漏洞 ID: %d 关联了 %d 个资产", vulnerability.ID, len(vulnerability.Assets))
		for i, asset := range vulnerability.Assets {
			log.Printf("关联资产 %d: ID=%d, 名称=%s", i+1, asset.ID, asset.Name)
		}
	} else {
		log.Printf("漏洞 ID: %d 没有关联资产，尝试使用原始SQL查询关联关系", vulnerability.ID)

		// 尝试通过原始SQL查询关联关系
		var assetIDs []uint
		err := utils.DB.Raw(`
			SELECT asset_id FROM vulnerability_assets 
			WHERE vulnerability_id = ?
		`, id).Scan(&assetIDs).Error

		if err != nil {
			log.Printf("查询关联资产失败: %v", err)
		} else if len(assetIDs) > 0 {
			log.Printf("通过SQL查询发现 %d 个关联资产: %v", len(assetIDs), assetIDs)

			// 查询资产详情
			var assets []models.Asset
			if err := utils.DB.Where("id IN ?", assetIDs).Find(&assets).Error; err != nil {
				log.Printf("获取关联资产详情失败: %v", err)
			} else {
				vulnerability.Assets = assets
				log.Printf("已加载 %d 个关联资产", len(assets))
			}
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取漏洞详情成功",
		"data":    vulnerability,
	})
}

// CreateVulnerability 创建新漏洞
func (v *VulnerabilityController) CreateVulnerability(c *gin.Context) {
	// 获取用户ID
	userID, exists := c.Get("userID")
	if !exists {
		log.Printf("用户ID未找到")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "用户ID未找到",
		})
		return
	}
	log.Printf("用户 ID: %v 尝试创建漏洞", userID)

	// 接收请求数据
	var requestData struct {
		Title       string  `json:"title"`
		CVE         string  `json:"cve_id"`
		Description string  `json:"description"`
		Type        string  `json:"type"`
		Severity    string  `json:"severity"`
		Status      string  `json:"status"`
		CVSS        float64 `json:"cvss"`
		Assets      []uint  `json:"assets"`
		Solution    string  `json:"solution"`
		References  string  `json:"references"`
		Steps       string  `json:"reproduce_steps"`
	}

	if err := c.ShouldBindJSON(&requestData); err != nil {
		log.Printf("创建漏洞请求参数错误: %v, 请求体: %v", err, c.Request.Body)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	log.Printf("接收到的创建漏洞数据: %+v", requestData)

	// 验证必填字段
	if requestData.Title == "" || requestData.Severity == "" || requestData.Type == "" {
		log.Printf("缺少必要的字段: title=%s, severity=%s, type=%s",
			requestData.Title, requestData.Severity, requestData.Type)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "缺少必要的字段: 标题、严重程度或漏洞类型",
		})
		return
	}

	// 安全地提取用户ID
	var reportedByID uint = 1 // 默认值
	switch v := userID.(type) {
	case float64:
		reportedByID = uint(v)
	case int:
		reportedByID = uint(v)
	case uint:
		reportedByID = v
	case int64:
		reportedByID = uint(v)
	case uint64:
		reportedByID = uint(v)
	default:
		log.Printf("无法转换用户ID类型: %T, 值: %v", userID, userID)
	}

	// 创建漏洞对象
	now := time.Now()
	vulnerability := models.Vulnerability{
		Title:            requestData.Title,
		Description:      requestData.Description,
		Type:             models.VulnType(requestData.Type),
		Severity:         models.Severity(requestData.Severity),
		Status:           models.VulnStatus(requestData.Status),
		CVE:              requestData.CVE,
		CVSS:             requestData.CVSS,
		StepsToReproduce: requestData.Steps,
		Solution:         requestData.Solution,
		References:       requestData.References,
		DiscoveredAt:     now,
		ReportedBy:       reportedByID,
		CreatedAt:        now,
		UpdatedAt:        now,
	}

	// 保存漏洞到数据库
	if err := utils.DB.Create(&vulnerability).Error; err != nil {
		log.Println("创建漏洞失败:", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "创建漏洞失败: " + err.Error(),
		})
		return
	}

	// 如果关联了资产，添加关联关系
	if len(requestData.Assets) > 0 {
		for _, assetID := range requestData.Assets {
			if err := utils.DB.Exec("INSERT INTO vulnerability_assets (vulnerability_id, asset_id) VALUES (?, ?)", vulnerability.ID, assetID).Error; err != nil {
				log.Printf("关联资产失败, 漏洞ID=%d, 资产ID=%d, 错误: %v", vulnerability.ID, assetID, err)
			}
		}
	}

	// 发送漏洞创建通知
	go func() {
		notificationManager, err := utils.NewNotificationManager()
		if err != nil {
			log.Printf("获取通知管理器失败: %v", err)
			return
		}
		notificationManager.SendVulnerabilityNotification(utils.EventVulnCreate, &vulnerability, "")
	}()

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "创建漏洞成功",
		"data": gin.H{
			"id": vulnerability.ID,
		},
	})
}

// UpdateVulnerability 更新漏洞信息
func (v *VulnerabilityController) UpdateVulnerability(c *gin.Context) {
	// 获取用户ID
	userID, _ := c.Get("userID")
	log.Printf("用户 ID: %v 尝试更新漏洞", userID)

	id := c.Param("id")
	log.Printf("准备更新漏洞, ID: %s", id)

	var vulnerability models.Vulnerability
	if err := utils.DB.First(&vulnerability, id).Error; err != nil {
		log.Printf("漏洞不存在, ID: %s, 错误: %v", id, err)
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": "漏洞不存在",
		})
		return
	}

	// 接收请求数据
	var requestData struct {
		Title       string  `json:"title"`
		CVE         string  `json:"cve_id"`
		Description string  `json:"description"`
		Type        string  `json:"type"`
		Severity    string  `json:"severity"`
		Status      string  `json:"status"`
		CVSS        float64 `json:"cvss"`
		Assets      []uint  `json:"assets"`
		Solution    string  `json:"solution"`
		References  string  `json:"references"`
		Steps       string  `json:"reproduce_steps"`
	}

	if err := c.ShouldBindJSON(&requestData); err != nil {
		log.Printf("更新漏洞请求参数错误: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	log.Printf("接收到的更新漏洞数据: %+v", requestData)

	// 保存以前的状态，用于判断状态是否变更
	oldStatus := vulnerability.Status

	// 更新基本字段
	vulnerability.Title = requestData.Title
	vulnerability.Description = requestData.Description
	vulnerability.Type = models.VulnType(requestData.Type)
	vulnerability.Severity = models.Severity(requestData.Severity)
	vulnerability.Status = models.VulnStatus(requestData.Status)
	vulnerability.CVE = requestData.CVE
	vulnerability.CVSS = requestData.CVSS
	vulnerability.Solution = requestData.Solution
	vulnerability.References = requestData.References
	vulnerability.StepsToReproduce = requestData.Steps
	vulnerability.UpdatedAt = time.Now()

	// 处理状态变更相关时间
	now := time.Now()
	if vulnerability.Status == models.StatusVerified && vulnerability.VerifiedAt == nil {
		vulnerability.VerifiedAt = &now
	} else if vulnerability.Status == models.StatusFixed && vulnerability.FixedAt == nil {
		vulnerability.FixedAt = &now
	} else if vulnerability.Status == models.StatusClosed && vulnerability.ClosedAt == nil {
		vulnerability.ClosedAt = &now
	}

	// 保存更新
	if err := utils.DB.Save(&vulnerability).Error; err != nil {
		log.Printf("更新漏洞失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "更新漏洞失败: " + err.Error(),
		})
		return
	}

	// 处理资产关联
	if requestData.Assets != nil {
		// 删除旧的关联
		if err := utils.DB.Exec("DELETE FROM vulnerability_assets WHERE vulnerability_id = ?", vulnerability.ID).Error; err != nil {
			log.Printf("删除漏洞资产关联失败: %v", err)
		}

		// 添加新的关联
		for _, assetID := range requestData.Assets {
			if err := utils.DB.Exec("INSERT INTO vulnerability_assets (vulnerability_id, asset_id) VALUES (?, ?)", vulnerability.ID, assetID).Error; err != nil {
				log.Printf("添加漏洞资产关联失败: %v", err)
			}
		}
	}

	// 发送通知
	go func() {
		notificationManager, err := utils.NewNotificationManager()
		if err != nil {
			log.Printf("获取通知管理器失败: %v", err)
			return
		}

		// 如果状态发生变化，发送状态变更通知
		if oldStatus != vulnerability.Status {
			notificationManager.SendVulnerabilityNotification(utils.EventVulnStatusChange, &vulnerability, string(oldStatus))
		} else {
			// 否则发送普通更新通知
			notificationManager.SendVulnerabilityNotification(utils.EventVulnUpdate, &vulnerability, "")
		}
	}()

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "更新漏洞成功",
		"data": gin.H{
			"id": vulnerability.ID,
		},
	})
}

// DeleteVulnerability 删除漏洞
func (v *VulnerabilityController) DeleteVulnerability(c *gin.Context) {
	// 获取用户ID
	userID, _ := c.Get("userID")
	log.Printf("用户 ID: %v 尝试删除漏洞", userID)

	id := c.Param("id")
	log.Printf("准备删除漏洞, ID: %s", id)

	var vulnerability models.Vulnerability
	if err := utils.DB.First(&vulnerability, id).Error; err != nil {
		log.Printf("漏洞不存在, ID: %s, 错误: %v", id, err)
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": "漏洞不存在",
		})
		return
	}

	log.Printf("找到待删除漏洞, ID: %d, 标题: %s", vulnerability.ID, vulnerability.Title)

	// 先清空关联资产
	if err := utils.DB.Model(&vulnerability).Association("Assets").Clear(); err != nil {
		log.Printf("清空漏洞关联资产失败: %v", err)
	}

	// 执行删除操作
	if err := utils.DB.Delete(&vulnerability).Error; err != nil {
		log.Printf("删除漏洞失败, ID: %d, 错误: %v", vulnerability.ID, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "删除漏洞失败",
			"error":   err.Error(),
		})
		return
	}

	// 发送漏洞删除通知
	go func() {
		notificationManager, err := utils.NewNotificationManager()
		if err != nil {
			log.Printf("获取通知管理器失败: %v", err)
			return
		}
		notificationManager.SendVulnerabilityNotification(utils.EventVulnDelete, &vulnerability, "")
	}()

	log.Printf("漏洞删除成功, ID: %d", vulnerability.ID)

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "删除漏洞成功",
	})
}

// BatchImportVulnerabilities 批量导入漏洞
func (v *VulnerabilityController) BatchImportVulnerabilities(c *gin.Context) {
	// 获取用户ID
	userID, exists := c.Get("userID")
	if !exists {
		log.Printf("用户ID未找到")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "用户ID未找到",
		})
		return
	}
	log.Printf("开始处理批量导入漏洞请求, 用户ID: %v", userID)

	// 安全地提取用户ID
	var reportedByID uint = 1 // 默认值
	switch v := userID.(type) {
	case float64:
		reportedByID = uint(v)
	case int:
		reportedByID = uint(v)
	case uint:
		reportedByID = v
	case int64:
		reportedByID = uint(v)
	case uint64:
		reportedByID = uint(v)
	default:
		log.Printf("无法转换用户ID类型: %T, 值: %v", userID, userID)
	}

	// 获取文件
	file, err := c.FormFile("file")
	if err != nil {
		log.Printf("获取上传文件失败: %v, 表单内容: %+v", err, c.Request.Form)
		// 尝试读取请求体，看是否有问题
		body, _ := c.GetRawData()
		log.Printf("请求体内容: %s", string(body))

		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请上传文件: " + err.Error(),
		})
		return
	}

	log.Printf("成功获取上传文件: %s, 大小: %d 字节", file.Filename, file.Size)

	// 检查文件类型
	filename := file.Filename
	var isJSON bool
	var isCSV bool

	if strings.HasSuffix(strings.ToLower(filename), ".json") {
		isJSON = true
	} else if strings.HasSuffix(strings.ToLower(filename), ".csv") {
		isCSV = true
	} else {
		log.Printf("不支持的文件类型: %s", filename)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "不支持的文件类型，请上传JSON或CSV文件",
		})
		return
	}

	// 打开文件
	openedFile, err := file.Open()
	if err != nil {
		log.Printf("打开文件失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "打开文件失败",
			"error":   err.Error(),
		})
		return
	}
	defer openedFile.Close()

	// 存储导入结果
	type ImportResult struct {
		Success       int      `json:"success"`
		Failed        int      `json:"failed"`
		FailedDetails []string `json:"failed_details"`
	}
	result := ImportResult{
		Success:       0,
		Failed:        0,
		FailedDetails: []string{},
	}

	// 解析文件并创建漏洞
	now := time.Now()

	if isJSON {
		// 处理JSON文件
		var vulnList []struct {
			Title       string  `json:"title"`
			CVE         string  `json:"cve_id"`
			Description string  `json:"description"`
			Type        string  `json:"type"`
			Severity    string  `json:"severity"`
			Status      string  `json:"status"`
			CVSS        float64 `json:"cvss"`
			Assets      []uint  `json:"assets"`
			Solution    string  `json:"solution"`
			References  string  `json:"references"`
			Steps       string  `json:"reproduce_steps"`
		}

		decoder := json.NewDecoder(openedFile)
		if err := decoder.Decode(&vulnList); err != nil {
			log.Printf("解析JSON文件失败: %v", err)
			c.JSON(http.StatusBadRequest, gin.H{
				"code":    400,
				"message": "解析JSON文件失败，请检查格式",
				"error":   err.Error(),
			})
			return
		}

		// 批量创建漏洞
		for i, vulnData := range vulnList {
			// 验证必填字段
			if vulnData.Title == "" || vulnData.Severity == "" || vulnData.Type == "" {
				msg := fmt.Sprintf("记录 #%d 缺少必填字段", i+1)
				result.Failed++
				result.FailedDetails = append(result.FailedDetails, msg)
				continue
			}

			// 创建漏洞对象
			vulnerability := models.Vulnerability{
				Title:            vulnData.Title,
				Description:      vulnData.Description,
				Type:             models.VulnType(vulnData.Type),
				Severity:         models.Severity(vulnData.Severity),
				Status:           models.VulnStatus(vulnData.Status),
				CVE:              vulnData.CVE,
				CVSS:             vulnData.CVSS,
				StepsToReproduce: vulnData.Steps,
				Solution:         vulnData.Solution,
				References:       vulnData.References,
				DiscoveredAt:     now,
				ReportedBy:       reportedByID,
				CreatedAt:        now,
				UpdatedAt:        now,
			}

			// 处理关联资产
			if len(vulnData.Assets) > 0 {
				var assets []models.Asset
				for _, assetID := range vulnData.Assets {
					var asset models.Asset
					if err := utils.DB.First(&asset, assetID).Error; err == nil {
						assets = append(assets, asset)
					}
				}
				vulnerability.Assets = assets
			}

			// 保存到数据库
			if err := utils.DB.Create(&vulnerability).Error; err != nil {
				log.Printf("创建漏洞 #%d (%s) 失败: %v", i+1, vulnData.Title, err)
				result.Failed++
				result.FailedDetails = append(result.FailedDetails, fmt.Sprintf("创建 %s 失败: %v", vulnData.Title, err))
				continue
			}

			result.Success++
		}
	} else if isCSV {
		// 处理CSV文件
		reader := csv.NewReader(openedFile)
		// 读取标题行
		headers, err := reader.Read()
		if err != nil {
			log.Printf("读取CSV标题行失败: %v", err)
			c.JSON(http.StatusBadRequest, gin.H{
				"code":    400,
				"message": "读取CSV标题行失败",
				"error":   err.Error(),
			})
			return
		}

		// 创建标题到索引的映射
		headerMap := make(map[string]int)
		for i, header := range headers {
			headerMap[strings.TrimSpace(strings.ToLower(header))] = i
		}

		// 检查必要的列是否存在
		requiredColumns := []string{"title", "severity", "type"}
		missingColumns := []string{}
		for _, col := range requiredColumns {
			if _, exists := headerMap[col]; !exists {
				missingColumns = append(missingColumns, col)
			}
		}

		if len(missingColumns) > 0 {
			msg := fmt.Sprintf("CSV缺少必要的列: %s", strings.Join(missingColumns, ", "))
			log.Printf(msg)
			c.JSON(http.StatusBadRequest, gin.H{
				"code":    400,
				"message": msg,
			})
			return
		}

		log.Printf("CSV标题有效，包含所有必需字段: %v", requiredColumns)

		// 读取并处理每一行
		lineNum := 2 // 从第二行开始（1是标题行）
		for {
			record, err := reader.Read()
			if err == io.EOF {
				break
			}
			if err != nil {
				log.Printf("读取CSV行 #%d 失败: %v", lineNum, err)
				result.Failed++
				result.FailedDetails = append(result.FailedDetails, fmt.Sprintf("读取行 #%d 失败: %v", lineNum, err))
				lineNum++
				continue
			}

			// 从CSV记录创建漏洞对象
			var vulnerability models.Vulnerability
			vulnerability.Title = getSafeString(record, headerMap, "title")
			vulnerability.Description = getSafeString(record, headerMap, "description")
			vulnerability.Type = models.VulnType(getSafeString(record, headerMap, "type"))
			vulnerability.Severity = models.Severity(getSafeString(record, headerMap, "severity"))
			vulnerability.Status = models.VulnStatus(getSafeString(record, headerMap, "status"))
			vulnerability.CVE = getSafeString(record, headerMap, "cve_id")

			// 处理CVSS，需要转换字符串为浮点数
			if cvssStr := getSafeString(record, headerMap, "cvss"); cvssStr != "" {
				if cvssVal, err := strconv.ParseFloat(cvssStr, 64); err == nil {
					vulnerability.CVSS = cvssVal
				}
			}

			vulnerability.StepsToReproduce = getSafeString(record, headerMap, "reproduce_steps")
			vulnerability.Solution = getSafeString(record, headerMap, "solution")
			vulnerability.References = getSafeString(record, headerMap, "references")
			vulnerability.DiscoveredAt = now
			vulnerability.ReportedBy = reportedByID
			vulnerability.CreatedAt = now
			vulnerability.UpdatedAt = now

			// 验证必填字段
			if vulnerability.Title == "" || string(vulnerability.Severity) == "" || string(vulnerability.Type) == "" {
				msg := fmt.Sprintf("行 #%d 缺少必填字段", lineNum)
				result.Failed++
				result.FailedDetails = append(result.FailedDetails, msg)
				lineNum++
				continue
			}

			// 处理资产关联（如果有）
			if assetsStr := getSafeString(record, headerMap, "assets"); assetsStr != "" {
				assetIDs := strings.Split(assetsStr, ",")
				var assets []models.Asset
				for _, idStr := range assetIDs {
					idStr = strings.TrimSpace(idStr)
					if idStr == "" {
						continue
					}

					assetID, err := strconv.Atoi(idStr)
					if err != nil {
						continue
					}

					var asset models.Asset
					if err := utils.DB.First(&asset, assetID).Error; err == nil {
						assets = append(assets, asset)
					}
				}
				vulnerability.Assets = assets
			}

			// 保存到数据库
			if err := utils.DB.Create(&vulnerability).Error; err != nil {
				log.Printf("创建漏洞 #%d (%s) 失败: %v", lineNum, vulnerability.Title, err)
				result.Failed++
				result.FailedDetails = append(result.FailedDetails, fmt.Sprintf("创建 %s 失败: %v", vulnerability.Title, err))
				lineNum++
				continue
			}

			result.Success++
			lineNum++
		}
	}

	// 返回导入结果
	var message string
	if result.Failed > 0 {
		message = fmt.Sprintf("导入完成，成功: %d, 失败: %d。请检查失败详情。", result.Success, result.Failed)
	} else {
		message = fmt.Sprintf("导入完成，成功: %d", result.Success)
	}

	log.Printf("漏洞批量导入结果: 成功=%d, 失败=%d", result.Success, result.Failed)
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": message,
		"data":    result,
	})
}

// getSafeString 安全地从CSV记录中获取字符串
func getSafeString(record []string, headerMap map[string]int, key string) string {
	if idx, exists := headerMap[key]; exists && idx < len(record) {
		return strings.TrimSpace(record[idx])
	}
	return ""
}

// BatchDeleteVulnerabilities 批量删除漏洞
func (v *VulnerabilityController) BatchDeleteVulnerabilities(c *gin.Context) {
	// 获取用户ID
	userID, _ := c.Get("userID")
	log.Printf("用户 ID: %v 尝试批量删除漏洞", userID)

	// 解析请求体中的漏洞ID列表
	var requestBody struct {
		IDs []uint `json:"ids" binding:"required"`
	}

	if err := c.ShouldBindJSON(&requestBody); err != nil {
		log.Printf("解析请求参数失败: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误: " + err.Error(),
		})
		return
	}

	if len(requestBody.IDs) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "未提供要删除的漏洞ID",
		})
		return
	}

	log.Printf("准备批量删除漏洞，ID数量: %d, IDs: %v", len(requestBody.IDs), requestBody.IDs)

	// 查询这些漏洞是否存在
	var vulns []models.Vulnerability
	if err := utils.DB.Where("id IN (?)", requestBody.IDs).Find(&vulns).Error; err != nil {
		log.Printf("查询漏洞失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "查询漏洞失败: " + err.Error(),
		})
		return
	}

	// 检查是否所有漏洞都存在
	if len(vulns) != len(requestBody.IDs) {
		log.Printf("部分漏洞不存在，请求ID数量: %d, 找到漏洞数量: %d", len(requestBody.IDs), len(vulns))
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "部分漏洞不存在",
		})
		return
	}

	// 执行批量删除
	if err := utils.DB.Where("id IN (?)", requestBody.IDs).Delete(&models.Vulnerability{}).Error; err != nil {
		log.Printf("批量删除漏洞失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "批量删除漏洞失败: " + err.Error(),
		})
		return
	}

	// 发送通知
	go func() {
		notificationManager, err := utils.NewNotificationManager()
		if err != nil {
			log.Printf("获取通知管理器失败: %v", err)
			return
		}

		// 使用第一个漏洞作为示例通知
		if len(vulns) > 0 {
			sampleVuln := vulns[0]
			sampleVuln.Title = fmt.Sprintf("批量删除 - %s 等%d个漏洞", sampleVuln.Title, len(requestBody.IDs))
			notificationManager.SendVulnerabilityNotification("delete", &sampleVuln, "")
		}
	}()

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": fmt.Sprintf("成功删除 %d 个漏洞", len(requestBody.IDs)),
		"data": gin.H{
			"deleted_count": len(requestBody.IDs),
		},
	})
}
